﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading.Tasks;
using TV_Organizer.Properties;
using System.IO;

namespace TV_Organizer.FileScanner
{
    public partial class FileScannerControl : UserControl
    {
        public FileScannerControl()
        {
            InitializeComponent();
        }

        public void ResizeFileScannerColumnsAsync()
        {
            this.Dispatcher.BeginInvoke(new System.Action(() =>
            {
                foreach (var column in this.FileScannerGridView.Columns)
                {
                    if (double.IsNaN(column.Width))
                        column.Width = column.ActualWidth;

                    column.Width = double.NaN;
                }
            }));
        }

        private void FileScannerListView_SourceUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
        {
            this.ResizeFileScannerColumnsAsync();
        }

        private void ProcessFileCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (!(sender is FrameworkElement)) return;
            var l_sender = sender as FrameworkElement;
            if (!this.FileScannerListView.SelectedItems.Contains(l_sender.DataContext)) return;

            foreach (var file in this.FileScannerListView.SelectedItems.OfType<File>())
                file.ProcessFile = true;
        }

        private void ProcessFileCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            if (!(sender is FrameworkElement)) return;
            var l_sender = sender as FrameworkElement;
            if (!this.FileScannerListView.SelectedItems.Contains(l_sender.DataContext)) return;

            foreach (var file in this.FileScannerListView.SelectedItems.OfType<File>())
                file.ProcessFile = false;
        }

        private void MenuEdit_Click(object sender, RoutedEventArgs e)
        {
            var l_window = new FileEditionWindow(this.FileScannerListView.SelectedItems.OfType<File>());
            l_window.ShowDialog();

            if (l_window.DialogResult.HasValue && l_window.DialogResult.Value)
                this.ResizeFileScannerColumnsAsync();
        }

        private void FileScannerListView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (!(e.OriginalSource is FrameworkElement)) return;
            var l_source = e.OriginalSource as FrameworkElement;

            if (e.ClickCount == 2 && l_source.DataContext is File)
            {
                var l_file = l_source.DataContext as File;
                var l_window = new FileEditionWindow(new List<File>() { l_file });
                l_window.ShowDialog();
            }
        }

        private void FileScannerListView_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effects = DragDropEffects.All;
            }
            else
            {
                e.Effects = DragDropEffects.None;
            }
        }

        private async void FileScannerListView_Drop(object sender, DragEventArgs e)
        {
            App.Instance.Window.DisplayBusyIndicator("Scanning...", "", Visibility.Collapsed);

            var tasks = new List<Task>();

            var l_data = e.Data.GetData(DataFormats.FileDrop);
            if (!(l_data is string[])) return;

            var l_paths = l_data as string[];

            await TaskEx.Run(() =>
            {
                Application.Current.Dispatcher.Invoke(new System.Action(() =>
                {
                    foreach (var path in l_paths)
                    {
                        if (System.IO.Directory.Exists(path))
                            FileScanner.Instance.ScanFolder(path, 0);
                        else if (System.IO.File.Exists(path))
                            FileScanner.Instance.Files.Add(new File(path));
                    }
                }));
            });

            App.Instance.Window.HideBusyIndicator();

            if (Settings.Default.AnalyzeFilesAfterLoad)
                FileScanner.Instance.AnalyzeAllFilesAsync();
        }

        private void CheckAllBoxesCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            foreach (var file in FileScanner.Instance.Files)
                file.ProcessFile = true;
        }

        private void CheckAllBoxesCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            foreach (var file in FileScanner.Instance.Files)
                file.ProcessFile = false;
        }

        private void EnterShowNameButton_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Not yet implemented :-\\");
        }

        private void ShowSelectionComboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (FileScanner.Instance.IsAnalyzing) return;

            if (!(sender is FrameworkElement)) return;
            var l_fe = (FrameworkElement)sender;

            if (!(l_fe.DataContext is File)) return;
            var l_file = (File)l_fe.DataContext;

            l_file.ProcessFile = true;
        }

        #region BUTTONS HANDLERS
        
        // SCAN BUTTON
        private void ScanButton_Click(object sender, RoutedEventArgs e)
        {
            Task.Factory.StartNew(() => FileScanner.Instance.Scan());
        }

        // ANALYZE BUTTON
        private void AnalyzeButton_Click(object sender, RoutedEventArgs e)
        {
            FileScanner.Instance.AnalyzeAllFilesAsync();
        }

        // FETCH EPISODES NAMES BUTTON
        private void FetchEpisodeButton_Click(object sender, RoutedEventArgs e)
        {
            var connector = ConnectorsManager.Instance.GetTVShowsConnector(Settings.Default.SelectedTVShowConnector);
            if (connector == null) return;

            var l_tasks = new List<Task>();
            foreach (var i_file in this.FileScannerListView.Items.OfType<File>())
            {
                l_tasks.Add(Task.Factory.StartNew((f) =>
                {
                    var file = f as File;
                    if (file.SelectedShow != null && file.Episode != (int)File.EpisodeProperty.DefaultMetadata.DefaultValue && file.Season != (int)File.SeasonProperty.DefaultMetadata.DefaultValue)
                    {
                        var l_episode = connector.GetEpisode(file.SelectedShow, file.Season, file.Episode);
                        if (l_episode != null)
                            file.EpisodeTitle = l_episode.Title;
                    }
                }, i_file));
            }

            Task.Factory.StartNew(() =>
            {
                Task.WaitAll(l_tasks.ToArray());
                this.ResizeFileScannerColumnsAsync();
            });
        }

        // PROCESS BUTTON
        private void ProcessButton_Click(object sender, RoutedEventArgs e)
        {
            Task.Factory.StartNew(() => FileScanner.Instance.Process());
        }

        // CLEAR BUTTON
        private void ClearButton_Click(object sender, RoutedEventArgs e)
        {
            FileScanner.Instance.Files.Clear();
        }

        #endregion

        private void FileScannerListView_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if(e.Key == Key.Delete)
            {
                foreach (var file in this.FileScannerListView.SelectedItems.OfType<File>().ToList())
                    FileScanner.Instance.Files.Remove(file);
            }
        }
    }
}
